package com.example.mq.clients;

import com.example.mq.common.BinaryTool;
import com.example.mq.common.Request;
import com.example.mq.common.Response;
import com.example.mq.common.payloads.*;
import com.example.mq.server.virtualhost.ExchangeType;

import java.io.*;
import java.net.Socket;
import java.util.UUID;

public class Consumer1 {
    private String clientTag = "consumer1"; // 客户端唯一身份标识

    private Socket clientSocket;

    private InputStream inputStream;
    private OutputStream outputStream;
    private DataInputStream dataInputStream;
    private DataOutputStream dataOutputStream;

    private boolean isReadResponse = false;

    private Thread responseThread;

    public Consumer1(String ip, int port) throws IOException {
        // 连接到服务器
        clientSocket = new Socket(ip, port);
    }

    public void start() {
        try {
            System.out.println("已连接到服务器");

            inputStream = clientSocket.getInputStream();
            outputStream = clientSocket.getOutputStream();
            dataInputStream = new DataInputStream(inputStream);
            dataOutputStream = new DataOutputStream(outputStream);

            responseThread = new Thread(() -> {
                Response response = new Response();
                while (true) {
                    while (isReadResponse) {
                        try {
                            response.setType(dataInputStream.readInt());
                            response.setLength(dataInputStream.readInt());
                            byte[] payload = new byte[response.getLength()];
                            int n = dataInputStream.read(payload);
                            if (n != response.getLength()) {
                                throw new IOException("响应格式出错!");
                            }
                            response.setPayload(payload);
                            dispatchResponse(response);
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
            responseThread.start();

            // 请求：声明交换机
            // 构造请求
            PayloadExchangeDeclare payloadExchangeDeclare = new PayloadExchangeDeclare();
            payloadExchangeDeclare.setRid(generateRid());
            payloadExchangeDeclare.setClientTag(clientTag);
            payloadExchangeDeclare.setExchangeName("exchange1");
            payloadExchangeDeclare.setExchangeType(ExchangeType.DIRECT);
            byte[] payload1 = BinaryTool.toBytes(payloadExchangeDeclare);
            Request request1 = new Request();
            request1.setType(0x1);
            request1.setLength(payload1.length);
            request1.setPayload(payload1);
            // 发送请求
            writeRequest(request1);
            // 接收响应
            // TODO

            // 请求：声明队列
            // 构造请求
            PayloadQueueDeclare payloadQueueDeclare = new PayloadQueueDeclare();
            payloadQueueDeclare.setRid(generateRid());
            payloadQueueDeclare.setClientTag(clientTag);
            payloadQueueDeclare.setQueueName("queue1");
            byte[] payload2 = BinaryTool.toBytes(payloadQueueDeclare);
            Request request2 = new Request();
            request2.setType(0x3);
            request2.setLength(payload2.length);
            request2.setPayload(payload2);
            // 发送请求
            writeRequest(request2);
            // 接收响应
            // TODO

            // 请求：订阅
            // 构造请求
            PayloadSubscribe payloadSubscribe = new PayloadSubscribe();
            payloadSubscribe.setRid(generateRid());
            payloadSubscribe.setClientTag(clientTag);
            payloadSubscribe.setQueueName("queue1");
            byte[] payload3 = BinaryTool.toBytes(payloadSubscribe);
            Request request3 = new Request();
            request3.setType(0x8);
            request3.setLength(payload3.length);
            request3.setPayload(payload3);
            // 发送请求
            writeRequest(request3);
            // TODO

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Client error: " + e.getMessage());
        }
    }

    private void dispatchResponse(Response response) throws IOException, ClassNotFoundException {
        if (response.getType() == 0xc) {
            PayloadResponseSubscribe payloadResponseSubscribe = (PayloadResponseSubscribe) BinaryTool.fromBytes(response.getPayload());
            System.out.println("0xc" + "为type的响应数据，rid为：" + payloadResponseSubscribe.getRid());
            String bodyStr = (String) BinaryTool.fromBytes(payloadResponseSubscribe.getBody());
            System.out.println("[ConsumerClient]: 获取消息：" + bodyStr);
            return;
        }
    }

    private String generateRid() {
        return "R-" + UUID.randomUUID().toString();
    }

    public void writeRequest(Request request) throws IOException {
        dataOutputStream.writeInt(request.getType());
        dataOutputStream.writeInt(request.getLength());
        dataOutputStream.write(request.getPayload());
        dataOutputStream.flush();
        System.out.println("[Connection] 发送请求! type=" + request.getType() + ", length=" + request.getLength());
    }

    public boolean isReadResponse() {
        return isReadResponse;
    }

    public void setReadResponse(boolean readResponse) {
        isReadResponse = readResponse;
    }
}
